package com.et114.core.utility;

import java.util.Calendar;
import java.util.Date;
import java.util.Locale;




/**
 * 此类用作德国周格式、中国常用日期格式的转换
 * 锟斤拷锟斤拷锟斤拷锟斤拷鹿锟斤拷芨锟绞斤拷锟斤拷泄锟斤拷锟斤拷锟斤拷诟锟绞斤拷锟阶拷锟�
 * @author daomingw
 */
public class DateConverter {

	/**
	 * 根据YYYYWWD来计算相应的日期 其中:
	 * YYYY表示年，WW标识周，D表示星期(星期一：1，...星期日:7)
	 * 应满足DATE(YYYYWWD)=DATE(YYYY011)+(WW-1)*7+(D-1)换算关系
	 * 其中 DATE(YYYY011)的确定：
	 * 如YYYY.01.01是星期一，则DATE(YYYY011)=YYYY.01.01
	 * 如YYYY.01.01是星期二，则DATE(YYYY011)=(YYYY-1).12.31
	 * 如YYYY.01.01是星期三，则DATE(YYYY011)=(YYYY-1).12.30
	 * 如YYYY.01.01是星期四，则DATE(YYYY011)=(YYYY-1).12.29
	 * 如YYYY.01.01是星期五，则DATE(YYYY011)=YYYY.01.04
	 * 如YYYY.01.01是星期六，则DATE(YYYY011)=YYYY.01.03
	 * 如YYYY.01.01是星期日，则DATE(YYYY011)=YYYY.01.02
	 * 德国日期转化为中国日期，输出格式自定义 
	 * 异常说明:日期格式不满足 YYYYWWD格式,抛出异常IllegalArgumentException
	 * @param deDate	德国日期，格式满足YYYYWWD
	 * @param format    输出返回日期格式 如：yyyy-MM-dd,yyyy.MM.dd
	 * @return
	 */
	public static String dateDeToZh(String deDate, String format) {
		if (deDate == null)
			throw new IllegalArgumentException("the args is Null");
		if (deDate.trim().length()!=7)
			throw new IllegalArgumentException(
					"the date format is error,it's format should be YYYYWWD");
		int week = GetterUtil.getInteger(deDate.substring(4, 6));
		int day = GetterUtil.getInteger(deDate.substring(6));
		// (WW-1)*7+(D-1)换算关系
		int days = (week - 1) * 7 + (day - 1);
		Calendar cal = getFirstDay(deDate);
		cal.add(Calendar.DATE, days);
		String year = String.valueOf(cal.get(Calendar.YEAR));
		if(year.length()>4)
			throw new IllegalArgumentException("the date format is error,the year:"+deDate.substring(0,4));
		return DateUtil.formatDate(cal.getTime(), format);

	}

	/**
	 * 
	 * @param deDate
	 *            德国的日期格式必须满足 YYYYWWD
	 * @param format
	 *            日期格式 如：yyyy-MM-dd,yyyy.MM.dd
	 * @return
	 */
	private static Calendar getFirstDay(String deDate) {
		Calendar cal = Calendar.getInstance(Locale.CHINA);
		String year = deDate.substring(0, 4);
		cal.set(Calendar.YEAR, Integer.parseInt(year) - 1);
		cal.set(Calendar.MONTH, 12);
		cal.set(Calendar.DATE, 1);//
		int week = cal.get(Calendar.DAY_OF_WEEK);
		if (week == Calendar.SUNDAY) {// 星期日
			cal.add(Calendar.DATE, 1);
		} else if (week == Calendar.MONDAY) {// 星期一
			// no change
		} else if (week == Calendar.TUESDAY) {// 星期二
			cal.add(Calendar.DATE, -1);
		} else if (week == Calendar.WEDNESDAY) {// 星期三
			cal.add(Calendar.DATE, -2);
		} else if (week == Calendar.THURSDAY) {// 星期四
			cal.add(Calendar.DATE, -3);
		} else if (week == Calendar.FRIDAY) {// 星期五
			cal.add(Calendar.DATE, 3);
		} else if (week == Calendar.SATURDAY) {// 星期六
			cal.add(Calendar.DATE, 2);
		}
		return cal;
	}

	private static Calendar getMinimalDaysInFirstWeek(String deDate) {
		Calendar cal = Calendar.getInstance(Locale.CHINA);
		String year = deDate.substring(0, 4);
		cal.set(Calendar.YEAR, Integer.parseInt(year) - 1);
		cal.set(Calendar.MONTH, 12);
		cal.set(Calendar.DATE, 1);//
		int days=4;
		int week = cal.get(Calendar.DAY_OF_WEEK);
		if (week == Calendar.SUNDAY) {// 星期日
			cal.add(Calendar.DATE,-2);
		} else if (week == Calendar.MONDAY) {// 星期一
			days=7;
		} else if (week == Calendar.TUESDAY) {// 星期二
			days=6;
		} else if (week == Calendar.WEDNESDAY) {// 星期三
			days=5;
		} else if (week == Calendar.THURSDAY) {// 星期四
			//
		} else if (week == Calendar.FRIDAY) {// 星期五
			cal.add(Calendar.DATE,-4);
		} else if (week == Calendar.SATURDAY) {// 星期六
			cal.add(Calendar.DATE,-3);
		}
		cal.setMinimalDaysInFirstWeek(days);
		return cal;
	}

	/**
	 * 把指定格式日期转化为德国周日期格式(YYYYWWD)
	 * 
	 * @param chDate 	满足由format指定格式的日期字符串
	 * 					如,yyyy-MM-dd等格式的日期
	 * 					若chDate为空则默认为当前时间
	 * @param format  	日期格式
	 * @return 			返回德国周日期格式(YYYYWWD)字符串
	 */
	public static String dateZhToDe(String chDate, String format) {
		Date date = DateUtil.parseDate(chDate, format);
		if(date==null)
			date=new Date();
		Calendar chCal = Calendar.getInstance();
		chCal.setFirstDayOfWeek(Calendar.MONDAY);
		Calendar _cal = getMinimalDaysInFirstWeek(chDate);
		chCal.setMinimalDaysInFirstWeek(_cal.getMinimalDaysInFirstWeek());
		chCal.setTime(date);
		
		//此处与使用DateFormat方式获取冲突，直接使用get field方式获取
		
		int year=chCal.get(Calendar.YEAR);
		//此处属于一月跨年的情况，存在该周属于上年的可能
		if(chCal.get(Calendar.MONTH)==Calendar.JANUARY){
			_cal.add(Calendar.DATE,chCal.get(Calendar.DATE));
			year = _cal.get(Calendar.YEAR);
		}
		//对于12月31是星期一并且是第一周的情况下，属于跨年度的问题，该周属于下年的情况，因此年度应加1
		if(chCal.get(Calendar.MONTH)==Calendar.DECEMBER
				&&chCal.get(Calendar.DATE)==31
				&&chCal.get(Calendar.DAY_OF_WEEK)==Calendar.MONDAY
				&&chCal.get(Calendar.WEEK_OF_YEAR)==1){
				year++;
		}
		int week_of_year = chCal.get(Calendar.WEEK_OF_YEAR);
		int week = chCal.get(Calendar.DAY_OF_WEEK);
		//由于系统中YYYYWWD中的D表示星期(星期一：1，...星期日:7)
		//而Calendar中get(Calendar.DAY_OF_WEEK)表示星期
		//(星期日:1,星期一：2，...星期六:7);
		week = week == 1 ? 7 : week - 1;
		
		StringBuffer weekDate = new StringBuffer();
		weekDate.append(year);
		//符合WW格式不足二位补0
		if(week_of_year<10)
			weekDate.append("0");
		weekDate.append(week_of_year);
		weekDate.append(week);
		return weekDate.toString();
	}

	public static void main(String[] args) {
//		Calendar end=Calendar.getInstance();
//		end.set(Calendar.YEAR,2050);
//		end.set(Calendar.MONTH,11);
//		end.set(Calendar.DATE,31);
//		Calendar cal=Calendar.getInstance();
//		for (;cal.before(end);cal.add(Calendar.DATE,1)) {
//			Date time = cal.getTime();
//			SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
//			String s1 = sf.format(time);
//			String deDate = dateZhToDe(s1, "yyyy-MM-dd");
//			String zhDate = dateDeToZh(deDate, "yyyy-MM-dd");
//			if(!s1.equals(zhDate)){
//				System.out.println("-----------转换不一致的结果-----------");
//				System.out.println("待转换日期 :"+s1);
//				System.out.println("zh to de="+deDate);
//				System.out.println("de to zh=" + zhDate);
//				System.out.println("-----------------------------------");
//			}
//		}
		String string = dateDeToZh("9999999","yyyy-MM-dd");
		System.out.println(string);
		String []weeks=new String[]{"2000012","2000113","2000112","2005011","2005072","2005117","2007017","2007064","2007502","2010111","2050305"};
		for (int i = 0; i < weeks.length; i++) {
			String zhdate = DateConverter.dateDeToZh(weeks[i],"yyyy-MM-dd");
			System.out.println(weeks[i]+"\t:"+zhdate);
		}
		
	}

}
